﻿using System;
using System.Collections.Generic;
using System.Linq;
using Model;

/// <summary>
/// Summary description for Repository
/// </summary>
public class Repository
{
    private BokoDbEntities _db = null;

    public Repository()
    {
        _db = new BokoDbEntities();
    }

    #region Add

    internal void AddProfile(Profile aprofile)
    {
        Profile aprofiles = new Profile();

        aprofile.UserId = SiteSecurity.GetUserId();

        _db.AddObject("Profiles", aprofile);
    }

    public void AddUserProfile(UserProfile newUser)
    {
        _db.AddToUserProfiles(newUser);

        Save();
    }

    internal void AddObject(string type, Object aObject)
    {
        _db.AddObject(type, aObject);
    }

    internal void AddQuestionType(QuestionType aQuestionType)
    {
        _db.QuestionTypes.AddObject(aQuestionType);
    }

    public int AddQuestion(Question NewQuestion)
    {
        _db.AddToQuestions(NewQuestion);

        Save();

        return NewQuestion.Id;
    }

    internal void AddOption(QOption aOption)
    {
        _db.AddToQOptions(aOption);
    }

    #endregion Add

    #region Get

    public Profile GetProfileByUserId(int userId)
    {
        return _db.Profiles.FirstOrDefault(x => x.UserId == userId);
    }

    public IQueryable<Question> GetAllQuestions()
    {
        var ql = (from qll in _db.Questions
                  select qll).AsQueryable();

        return ql;
    }

    public List<QuestionType> GetQTypeList()
    {
        List<QuestionType> tps = (from tp in _db.QuestionTypes
                                  orderby tp.QTId
                                  select tp).ToList();

        return tps;
    }

    public QuestionType GetQuestionTypeById(int? requestId)
    {
        QuestionType qTObject = _db.QuestionTypes.FirstOrDefault(x => x.QTId == requestId);

        return qTObject;
    }

    internal Question GetAQuestionRandomly()
    {
        Question aQuestion = null;

        Profile aProfile = GetProfileByUserId(SiteSecurity.GetUserId());

        if (aProfile != null)
        {
            aQuestion = (from question in _db.Questions
                         where
                         question.IsAnswered == 0 &&
                         question.ReadingClass <= aProfile.ReadingClass
                         select question).FirstOrDefault();

            if (aQuestion != null)
            {
                aQuestion.IsAnswered = 1;
                aQuestion.AnswerStatus = Question.CantAnswered; 
                aQuestion.UserId = aProfile.UserId;
                aQuestion.AnsweringDate = DateTime.Now;
                Save();
            }
        }

        return aQuestion;
    }

    internal List<QOption> GetQOptionsByQuestionId(int questionId)
    {
        List<QOption> qOptionList = (from list in _db.QOptions
                                     where list.QId == questionId
                                     select list).ToList();

        return qOptionList;
    }

    internal Question GetAQuestionById(int questionId)
    {
        Question aQuestion = _db.Questions.FirstOrDefault(x => x.Id == questionId);

        return aQuestion;
    }

    internal IQueryable<Question> GetAnsweredQuestionsAUserByuserId(int userId)
    {
        var ql = (from qll in _db.Questions
                  where qll.IsAnswered > 0 && qll.UserId == userId
                  select qll).AsQueryable();

        return ql;
    }

    internal int GetNumberOfQuestionAnsweredToday()
    {
        DateTime now = DateTime.Now;

        int currentUserid = SiteSecurity.GetUserId();

        int questionsAnsweredToday = (from pf in _db.Questions
                                      where pf.AnsweringDate == now && pf.UserId == currentUserid
                                      select pf).Count();

        return questionsAnsweredToday;
    }

    #endregion Get

    #region Update

    public bool UpDateProfile()
    {
        return Convert.ToBoolean(_db.SaveChanges());
    }

    internal void UpdateQuestionByIdAndObject(Question aQuestion)
    {
        Question updateQuestion = GetAQuestionById(aQuestion.Id);

        updateQuestion.SpendingTime = aQuestion.SpendingTime;
        updateQuestion.IsAnswered = aQuestion.IsAnswered;
        updateQuestion.AnswerStatus= aQuestion.AnswerStatus;
        
        float results = 0;

        if (aQuestion.IsAnswered != 1)
        {
            results = (((float)updateQuestion.TotalAnsweringTime - (float)updateQuestion.SpendingTime) / (float)updateQuestion.TotalAnsweringTime) * 100;
        }

        updateQuestion.Results = results;

        Save();
    }

    internal void UpdateQuestionByIdAndObjectNoTimeLimit(Question aQuestion)
    {
        Question updateQuestion = GetAQuestionById(aQuestion.Id);

        updateQuestion.SpendingTime = aQuestion.SpendingTime;
        updateQuestion.IsAnswered = aQuestion.IsAnswered;
        updateQuestion.AnswerStatus = aQuestion.AnswerStatus;
        float results = 0;

        if (aQuestion.IsAnswered != 1)
        {
            if (updateQuestion.SpendingTime > updateQuestion.TotalAnsweringTime)
            {
                if (aQuestion.IsAnswered == 2)
                {
                    results = 100;
                }
            }
            else
            {
                if (aQuestion.IsAnswered == 2)
                {
                    results = 100 + (((float)updateQuestion.TotalAnsweringTime - (float)updateQuestion.SpendingTime) / (float)updateQuestion.TotalAnsweringTime) * 100;
                }
            }
        }

        updateQuestion.Results = results;

        Save();
    }

    #endregion Update

    #region Delete

    internal void DeleteQuestionById(int requestId)
    {
        Question deleteQbject = GetAQuestionById(requestId);

        _db.Questions.DeleteObject(deleteQbject);

        Save();
    }

    internal void DeleteQuestionTypeById(int requestId)
    {
        QuestionType deleteQbject = GetQuestionTypeById(requestId);

        _db.QuestionTypes.DeleteObject(deleteQbject);

        Save();
    }

    #endregion Delete

    #region misc

    public bool SaveChanges()
    {
        return Convert.ToBoolean(_db.SaveChanges());
    }

    public void Save()
    {
        _db.SaveChanges();
    }

    internal void ReloadAllQuestion()
    {
        IQueryable<Question> IqQ = _db.Questions;
        foreach (Question item in IqQ)
        {
            item.IsAnswered = 0;
            item.AnswerStatus = Question.NotAnswered;
            item.AnsweringDate = null;
            item.Results = 0;
            item.UserId = 0;            
        }
        Save();
    }

    #endregion misc
}